package com.sky.service.impl;

import cn.mybatis.mp.core.sql.executor.chain.QueryChain;
import com.sky.entity.Books;
import com.sky.mapper.BookcategoriesMapper;
import com.sky.mapper.UserborrowhistoryMapper;
import com.sky.mapper.UsersMapper;
import com.sky.mapper.BooksMapper;
import com.sky.service.DashboardService;
import com.sky.vo.CategoryStatVO;
import com.sky.vo.DashboardCoreMetricsVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.ArrayList;
import java.time.DayOfWeek;
import java.util.Arrays;

import com.sky.vo.PopularBookVO;
import com.sky.vo.ReaderBehaviorVO;

@Service
@Slf4j
public class DashboardServiceImpl implements DashboardService {

    @Autowired
    private UserborrowhistoryMapper userborrowhistoryMapper;
    
    @Autowired
    private UsersMapper usersMapper;

    @Autowired
    private BookcategoriesMapper bookcategoriesMapper;

    @Autowired
    private BooksMapper booksMapper;

    @Override
    public DashboardCoreMetricsVO getCoreMetrics() {
        // 获取今天的开始和结束时间
        LocalDateTime todayStart = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);
        LocalDateTime todayEnd = LocalDateTime.of(LocalDate.now(), LocalTime.MAX);
        
        // 获取昨天的开始和结束时间
        LocalDateTime yesterdayStart = todayStart.minusDays(1);
        LocalDateTime yesterdayEnd = todayEnd.minusDays(1);

        // 转换为Date类型
        Date todayStartDate = Date.from(todayStart.atZone(ZoneId.systemDefault()).toInstant());
        Date todayEndDate = Date.from(todayEnd.atZone(ZoneId.systemDefault()).toInstant());
        Date yesterdayStartDate = Date.from(yesterdayStart.atZone(ZoneId.systemDefault()).toInstant());
        Date yesterdayEndDate = Date.from(yesterdayEnd.atZone(ZoneId.systemDefault()).toInstant());

        // 1. 今日总借阅量
        Integer todayBorrowings = userborrowhistoryMapper.countBorrowingsByTimeRange(todayStartDate, todayEndDate);
        Integer yesterdayBorrowings = userborrowhistoryMapper.countBorrowingsByTimeRange(yesterdayStartDate, yesterdayEndDate);
        double borrowingsTrend = calculateTrend(todayBorrowings, yesterdayBorrowings);

        // 2. 当前借出数（实时）
        Integer currentBorrowings = userborrowhistoryMapper.countCurrentBorrowings();
        Integer yesterdayCurrentBorrowings = userborrowhistoryMapper.countBorrowingsAtTime(yesterdayEndDate);
        double currentBorrowingsTrend = calculateTrend(currentBorrowings, yesterdayCurrentBorrowings);

        // 3. 当前逾期数量（实时）
        Integer currentOverdue = userborrowhistoryMapper.countCurrentOverdue();
        Integer yesterdayOverdue = userborrowhistoryMapper.countOverdueAtTime(yesterdayEndDate);
        double overdueTrend = calculateTrend(currentOverdue, yesterdayOverdue);

        // 4. 今日新增用户数
        Integer todayNewUsers = usersMapper.countNewUsersByTimeRange(todayStartDate, todayEndDate);
        Integer yesterdayNewUsers = usersMapper.countNewUsersByTimeRange(yesterdayStartDate, yesterdayEndDate);
        double newUsersTrend = calculateTrend(todayNewUsers, yesterdayNewUsers);

        // 构建返回对象
        return DashboardCoreMetricsVO.builder()
                .totalBorrowings(buildMetricData(todayBorrowings, borrowingsTrend))
                .currentBorrowings(buildMetricData(currentBorrowings, currentBorrowingsTrend))
                .overdueItems(buildMetricData(currentOverdue, overdueTrend))
                .newUsers(buildMetricData(todayNewUsers, newUsersTrend))
                .build();
    }

    /**
     * 计算变化率
     * @param current 当前值
     * @param previous 前一个值
     * @return 变化率
     */
    private double calculateTrend(Integer current, Integer previous) {
        if (previous == 0) {
            return current > 0 ? 100.0 : 0.0;
        }
        return ((double) (current - previous) / previous) * 100;
    }

    /**
     * 构建指标数据对象
     * @param value 值
     * @param trend 变化率
     * @return MetricData对象
     */
    private DashboardCoreMetricsVO.MetricData buildMetricData(Integer value, double trend) {
        return DashboardCoreMetricsVO.MetricData.builder()
                .value(value)
                .trend(trend)
                .build();
    }

    /**
     * 获取图书分类占比统计数据
     * 统计逻辑：
     * 1. 获取所有分类的统计数据
     * 2. 计算总图书数和占比
     * 3. 只返回前5个分类，其余归类为"其他"
     * 
     * @return 分类统计数据列表
     */
    @Override
    public List<CategoryStatVO> getCategoryStats() {
        // 获取所有分类的统计数据
        List<Map<String, Object>> stats = bookcategoriesMapper.selectCategoryStats();
        
        // 如果没有数据，返回空列表
        if (stats.isEmpty()) {
            return new ArrayList<>();
        }

        // 转换为CategoryStatVO列表
        List<CategoryStatVO> allCategoryStats = stats.stream()
                .map(map -> CategoryStatVO.builder()
                        .categoryName((String) map.get("categoryName"))
                        .count(((Number) map.get("count")).intValue())
                        .build())
                .collect(Collectors.toList());

        // 计算总图书数
        int totalBooks = allCategoryStats.stream()
                .mapToInt(CategoryStatVO::getCount)
                .sum();

        List<CategoryStatVO> result = new ArrayList<>();
        
        // 处理前5个分类
        int othersCount = 0;
        for (int i = 0; i < allCategoryStats.size(); i++) {
            CategoryStatVO stat = allCategoryStats.get(i);
            if (i < 5) {
                // 计算前5个分类的占比
                double percentage = (stat.getCount() * 100.0) / totalBooks;
                stat.setPercentage(Math.round(percentage * 10.0) / 10.0);
                result.add(stat);
            } else {
                // 累加其他分类的数量
                othersCount += stat.getCount();
            }
        }
        
        // 如果有其他分类，添加到结果中
        if (othersCount > 0) {
            double othersPercentage = (othersCount * 100.0) / totalBooks;
            result.add(CategoryStatVO.builder()
                    .categoryName("其他")
                    .count(othersCount)
                    .percentage(Math.round(othersPercentage * 10.0) / 10.0)
                    .build());
        }
        
        return result;
    }

    /**
     * 获取热门图书列表
     * 直接根据图书的热度分数排序
     * 返回热度最高的5本图书
     * 
     * @return 热门图书列表
     */
    @Override
    public List<PopularBookVO> getPopularBooks() {
        List<Map<String, Object>> results = booksMapper.selectPopularBooks();

        return results.stream()
                .map(map -> PopularBookVO.builder()
                        .bookId(((Number) map.get("bookId")).longValue())
                        .bookName((String) map.get("bookName"))
                        .borrowCount(((Number) map.get("borrowCount")).intValue())
                        .build())
                .collect(Collectors.toList());
    }

    /**
     * 获取本周读者活跃度数据
     * 统计逻辑：
     * 1. 获取本周的每一天日期
     * 2. 统计每天的借阅和归还总次数
     * 3. 返回周一到周日的活跃度数据
     * 
     * @return 读者活跃度数据
     */
    @Override
    public ReaderBehaviorVO getReaderBehavior() {
        // 获取本周一的日期
        LocalDate monday = LocalDate.now().with(DayOfWeek.MONDAY);
        List<String> days = Arrays.asList("周一", "周二", "周三", "周四", "周五", "周六", "周日");
        List<Integer> activities = new ArrayList<>();

        // 统计本周每天的活跃度
        for (int i = 0; i < 7; i++) {
            LocalDate date = monday.plusDays(i);
            Date sqlDate = Date.from(date.atStartOfDay(ZoneId.systemDefault()).toInstant());
            Integer activity = userborrowhistoryMapper.countDailyActivity(sqlDate);
            activities.add(activity);
        }

        return ReaderBehaviorVO.builder()
                .days(days)
                .activities(activities)
                .build();
    }
} 